package com.netdevsdk.demo.playback.play;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Vector;

import javax.swing.JOptionPane;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.LongByReference;

import com.netdevsdk.demo.NetDemo;
import com.netdevsdk.demo.util.Common;
import com.netdevsdk.lib.NetDEVSDKLib.NETDEV_FILECOND_S;
import com.netdevsdk.lib.NetDEVSDKLib.NETDEV_FINDDATA_S;
import com.netdevsdk.lib.NetDEVSDKLib.NETDEV_IVA_SHOW_RULE_E;
import com.netdevsdk.lib.NetDEVSDKLib.NETDEV_PLAYBACKCOND_S;
import com.netdevsdk.lib.NetDEVSDKLib.NETDEV_TRANS_PROTOCAL_E;
import com.netdevsdk.lib.NetDEVSDKLib.NETDEV_VIDEO_CODE_TYPE_E;
import com.netdevsdk.lib.NetDEVSDKLib.NETDEV_VOD_PLAY_CTRL_E;

public class QueryAlarmPlayBackRecord {

    public static void queryPlayBack() {
        if(null == NetDemo.lpUserID) {
            JOptionPane.showMessageDialog(null, "Please Login device first. error code"+NetDemo.netdevsdk.NETDEV_GetLastError());
            return;
        }
        
        if(NetDemo.ChannelID == 0) {
            JOptionPane.showMessageDialog(null, "Please select an online channel.");
            return;
        }
        
        String beginTime =NetDemo.DCAlarmPlayBackBeginTime.jTextFieldDate.getText();
        String endTime = NetDemo.DCAlarmPlayBackEndTime.jTextFieldDate.getText();    
        if(false == Common.isValidDate(beginTime, NetDemo.DateFormat) ||false == Common.isValidDate(endTime, NetDemo.DateFormat)){
            JOptionPane.showMessageDialog(null, "Please check that the time format is correct.");
            return;
        }
        long getBeginTime=Common.date2TimeStamp(beginTime, NetDemo.DateFormat);
        long getEndTime=Common.date2TimeStamp(endTime, NetDemo.DateFormat);
        if(getBeginTime>getEndTime) {
            JOptionPane.showMessageDialog(null, " The start time cannot exceed the end time");
            return;
        }
        
        NETDEV_FILECOND_S pstFindCond = new NETDEV_FILECOND_S();
        pstFindCond.dwChannelID = NetDemo.ChannelID;
        pstFindCond.tBeginTime = Common.date2TimeStamp(beginTime, NetDemo.DateFormat);
        pstFindCond.tEndTime = Common.date2TimeStamp(endTime, NetDemo.DateFormat);
        pstFindCond.dwRecordLocation = 1;
        
        int fileType = 0;
        switch (NetDemo.comboBoxQueryAlarmPlaybackType.getSelectedIndex()) {
        case 0: 
            fileType = 28;
            break;
        default:
            break;
        }
        pstFindCond.dwFileType = fileType;
        NetDemo.AlarmPlayBackTableModel.setRowCount(0);
        
        Pointer lpFindHandle = NetDemo.netdevsdk.NETDEV_FindFile_V30(NetDemo.lpUserID, pstFindCond);
        if(null != lpFindHandle){
            NETDEV_FINDDATA_S pstFindData = new NETDEV_FINDDATA_S();
            boolean bRet = NetDemo.netdevsdk.NETDEV_FindNextFile(lpFindHandle, pstFindData);
            if(!bRet) {
                JOptionPane.showMessageDialog(null, "Get the record failed. error code"+NetDemo.netdevsdk.NETDEV_GetLastError());
                return;         
            }
            while(bRet){
                Vector<String> vector = new Vector<>();
                vector.add(Common.timeStamp2Date(String.valueOf(pstFindData.tBeginTime), NetDemo.DateFormat));
                vector.add(Common.timeStamp2Date(String.valueOf(pstFindData.tEndTime), NetDemo.DateFormat));
                vector.add(Integer.toString(pstFindData.dwFileType));
                NetDemo.AlarmPlayBackTableModel.insertRow(0,vector);
                bRet = NetDemo.netdevsdk.NETDEV_FindNextFile(lpFindHandle, pstFindData);
            }           
            NetDemo.netdevsdk.NETDEV_FindClose(lpFindHandle);
        }else {
            JOptionPane.showMessageDialog(null, "No data");
        }
    }

    public static void playBack() {
        if(null == NetDemo.lpUserID) {
            JOptionPane.showMessageDialog(null, "Please Login device first. error code"+NetDemo.netdevsdk.NETDEV_GetLastError());
            return;
        }
        if(NetDemo.alarmPlayBackTable.getSelectedRow()<0) {
            JOptionPane.showMessageDialog(null, "No file,please choose a file");
            return;
        }  
        if(null != NetDemo.lpPlayHandle) {
            JOptionPane.showMessageDialog(null, "A video is playing now, please stop first.");
            return;
        }
        
        NetDemo.jButtonStopAlarmPlayBack.setEnabled(true);
        NetDemo.jButtonMic.setVisible(false);
        NetDemo.jSliderLiveMicSound.setVisible(false);
        NetDemo.jLabelLiveSound2.setVisible(false);
        NetDemo.jLableLiveMicSound.setVisible(false);
        NetDemo.jLabelLiveViewStreamUrl.setText(null);
        
        int row=NetDemo.alarmPlayBackTable.getSelectedRow();
        String Beginstr=(String)NetDemo.alarmPlayBackTable.getValueAt(row, 0);
        String Endstr=(String)NetDemo.alarmPlayBackTable.getValueAt(row, 1);
        String strFileTypeString = (String) NetDemo.alarmPlayBackTable.getValueAt(row, 2);
        NETDEV_PLAYBACKCOND_S pstPlayBackCond=new NETDEV_PLAYBACKCOND_S();
        pstPlayBackCond.dwChannelID = NetDemo.ChannelID;
        pstPlayBackCond.hPlayWnd = Native.getComponentPointer(NetDemo.panelPlayLabel);
        pstPlayBackCond.tBeginTime = Common.date2TimeStamp(Beginstr, NetDemo.DateFormat);
        pstPlayBackCond.tEndTime = Common.date2TimeStamp(Endstr, NetDemo.DateFormat);
        pstPlayBackCond.dwLinkMode = NETDEV_TRANS_PROTOCAL_E.NETDEV_TRANS_PROTOCAL_TCP;
        pstPlayBackCond.dwRecordLocation = 1;
        pstPlayBackCond.dwFileType = Integer.valueOf(strFileTypeString);
        Pointer ReplayUrl=new Memory(260);
        
        boolean bRet= NetDemo.netdevsdk.NETDEV_GetReplayUrl_V30(NetDemo.lpUserID, pstPlayBackCond, ReplayUrl);    
        if(bRet) {
            byte[] szReplayUrl=ReplayUrl.getByteArray(0, 260);
            String pszReplayUrl=null;
            try {
                pszReplayUrl=new String(szReplayUrl,"GB2312");
                NetDemo.jLabelLiveViewStreamUrl.setText(pszReplayUrl);
            }catch(UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            
            NetDemo.lpPlayHandle=NetDemo.netdevsdk.NETDEV_PlayBackByUrl(NetDemo.lpUserID, pszReplayUrl, pstPlayBackCond);
            if(null != NetDemo.lpPlayHandle){
                /* 回放播放成功时需要设置元数据才能看到轨迹框 */
                boolean bRet1=NetDemo.netdevsdk.NETDEV_SetIVAEnable(NetDemo.lpPlayHandle,1);
                if(bRet1) {
                    int dwShowParam = NETDEV_IVA_SHOW_RULE_E.NETDEV_IVA_SHOW_RULE + NETDEV_IVA_SHOW_RULE_E.NETDEV_IVA_SHOW_RESULT_TOUTH_RULE
                            +NETDEV_IVA_SHOW_RULE_E.NETDEV_IVA_SHOW_RESULT_UNTOUTH_RULE + NETDEV_IVA_SHOW_RULE_E.NETDEV_IVA_SHOW_TRACK;
                    boolean bRet2= NetDemo.netdevsdk.NETDEV_SetIVAShowParam(dwShowParam);
                    if(!bRet2) {
                        JOptionPane.showMessageDialog(null, "Set failed,please fist start live,if already,maybe not support,error code"+NetDemo.netdevsdk.NETDEV_GetLastError());
                        System.out.printf("NETDEV_SetIVAShowParam failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                        }
                    }else {
                        JOptionPane.showMessageDialog(null, "Set failed,please fist start live,"+NetDemo.netdevsdk.NETDEV_GetLastError());
                        System.out.printf("NETDEV_SetIVAEnable failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                        }
                NetDemo.jSliderAlarmPlayBack.setMaximum((int)pstPlayBackCond.tEndTime);
                NetDemo.jSliderAlarmPlayBack.setMinimum((int)pstPlayBackCond.tBeginTime);
                NetDemo.netdevsdk.NETDEV_SetMuteStatus(NetDemo.lpPlayHandle,1);
                NetDemo.netdevsdk.NETDEV_OpenSound(NetDemo.lpPlayHandle);
                Thread singlePlayBackByURLThread=new Thread(new Runnable() {
                    @Override
                    public void run() {
                        int nCount = 0;
                        int endCount = 0;
                        /* 回放视频流实际结束时间 */
                        long realEndTime = 0L;
                        while(true)
                        {
                            /* 获取窗口码率 */
                            IntByReference pdwBitRate = new IntByReference();
                            boolean bRetBit = NetDemo.netdevsdk.NETDEV_GetBitRate(NetDemo.lpPlayHandle,pdwBitRate);
                            if(bRetBit != true)
                            {
                                System.out.printf("NETDEV_GetBitRate failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                                return;
                            }
                            NetDemo.jLabelBitRateParam.setText(String.valueOf(pdwBitRate.getValue()));
                            
                            /* 获取窗口帧率 */
                            IntByReference pdwFrameRate = new IntByReference();
                            boolean bRet2 = NetDemo.netdevsdk.NETDEV_GetFrameRate(NetDemo.lpPlayHandle,pdwFrameRate);
                            if(bRet2 != true)
                            {
                                System.out.printf("NETDEV_GetFrameRate failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                                return;
                            }
                            NetDemo.jLabelFrameRate.setText(String.valueOf(pdwFrameRate.getValue()));
                            
                            /* 获取窗口编码格式 */
                            IntByReference pdwVideoEncFmt = new IntByReference();
                            boolean bRet3 = NetDemo.netdevsdk.NETDEV_GetVideoEncodeFmt(NetDemo.lpPlayHandle,pdwVideoEncFmt);
                            if(bRet3 != true)
                            {
                                System.out.printf("NETDEV_GetVideoEncodeFmt failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                                return;
                            }
                            String showEncodeFmt=null;
                            if(pdwVideoEncFmt.getValue()==NETDEV_VIDEO_CODE_TYPE_E.NETDEV_VIDEO_CODE_MJPEG){
                                showEncodeFmt="MJPEG";
                            }else if(pdwVideoEncFmt.getValue()==NETDEV_VIDEO_CODE_TYPE_E.NETDEV_VIDEO_CODE_H264) {
                                showEncodeFmt="H.264";
                            }else if(pdwVideoEncFmt.getValue()==NETDEV_VIDEO_CODE_TYPE_E.NETDEV_VIDEO_CODE_H265) {
                                showEncodeFmt="H.265";
                            }
                            NetDemo.jLabelVideoEncodeFmt.setText(showEncodeFmt);
                            
                            /* 获取视频分辨率 */
                            IntByReference pdwWidth = new IntByReference();
                            IntByReference pdwHeight = new IntByReference();
                            boolean bRet4 = NetDemo.netdevsdk.NETDEV_GetResolution(NetDemo.lpPlayHandle,pdwWidth,pdwHeight);
                            if(bRet4 != true)
                            {
                                System.out.printf("NETDEV_GetResolution failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                                return;
                            }
                            NetDemo.jLabelGetpdwWidth.setText(String.valueOf(pdwWidth.getValue())+"x");
                            NetDemo.jLabelGetpdwHeight.setText(String.valueOf(pdwHeight.getValue()));


                            /* 获取窗口丢包率 */
                            IntByReference pURLReceivePacketNum = new IntByReference();
                            IntByReference pURLLostPktNum = new IntByReference();
                            boolean bRet5 = NetDemo.netdevsdk.NETDEV_GetLostPacketRate(NetDemo.lpPlayHandle,pURLReceivePacketNum,pURLLostPktNum);
                            if(bRet5 != true)
                            {
                                System.out.printf("NETDEV_GetLostPacketRate failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                                return;
                            }
                            double lostPacketRate=0.0;
                            if(pURLLostPktNum.getValue()==0) {
                                lostPacketRate=0.0;
                            }else {
                                BigDecimal receive=new BigDecimal(pURLReceivePacketNum.getValue());
                                BigDecimal lost=new BigDecimal(pURLLostPktNum.getValue());
                                BigDecimal sum=receive.add(lost);
                                try {
                                    BigDecimal result=receive.divide(sum,2,BigDecimal.ROUND_HALF_UP);
                                    lostPacketRate=result.doubleValue();
                                } catch (Exception e) {                                  
                                    return;
                                }
                            }
                            NetDemo.jLabelGetpulRecvPktNum.setText(String.valueOf(lostPacketRate));

                            /* 获取静音状态 */
                            IntByReference pbMute=new IntByReference();
                            boolean bRet6= NetDemo.netdevsdk.NETDEV_GetMuteStatus(NetDemo.lpPlayHandle, pbMute);
                            if(!bRet6) {
                                System.out.printf("NETDEV_GetMuteStatus failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                                return;
                            }
                            NetDemo.getMute=pbMute.getValue();
                            
                            /* 控制录像回放的状态 */
                            LongByReference PlayTime = new LongByReference();
                            boolean bRet = NetDemo.netdevsdk.NETDEV_PlayBackControl(NetDemo.lpPlayHandle, NETDEV_VOD_PLAY_CTRL_E.NETDEV_PLAY_CTRL_GETPLAYTIME, PlayTime);
                            if(bRet){
                                
                                long lTime = PlayTime.getValue();
                                /* 当实际收到的视频流小于回放录像文件的结束时间时进行判断，连续获取3次以上相同播放进度时判断为视频流已结束，停止播放 */
                                if(lTime == realEndTime) {
                                    endCount++;
                                }else {
                                    realEndTime = lTime;
                                    endCount = 0;
                                }
                                NetDemo.jSliderAlarmPlayBack.setValue((int)lTime);
                                long lRemainTime = (long)NetDemo.jSliderAlarmPlayBack.getMaximum() - lTime;
                                String strRemainTime = String.valueOf(lRemainTime/60/60) + ":" + String.valueOf((lRemainTime/60)%60) + ":"+ String.valueOf(lRemainTime%60);
                                String strInfo = Common.timeStamp2Date(String.valueOf(lTime), NetDemo.DateFormat);
                                strInfo += " / ";
                                strInfo += strRemainTime;
                                NetDemo.lblAlarmProgressLabel.setText(strInfo);
                                nCount = 0;
                            }else {
                                nCount++;
                                System.out.println("Get playback time failed");
                            }
                            
                            if((PlayTime.getValue()) >= ((long)NetDemo.jSliderAlarmPlayBack.getMaximum()) || nCount>3 || endCount >3){
                            	stopPlayBack();
                                break;
                            }
                            
                            try{
                                Thread.sleep(700);
                            }catch(InterruptedException e){
                                e.printStackTrace();
                            }
                        }

                    }
                });
                NetDemo.singleLiveThread.execute(singlePlayBackByURLThread);
            }
        }else {
            System.out.println("NETDEV_GetReplayUrl, error:" + NetDemo.netdevsdk.NETDEV_GetLastError());
            return;
        }
    }

    public static void stopPlayBack() {

        if(null != NetDemo.lpPlayHandle){
            NetDemo.netdevsdk.NETDEV_StopPlayBack(NetDemo.lpPlayHandle);
            NetDemo.lpPlayHandle = null;
        }
        
        NetDemo.jButtonPauseAlarmPlayBack.setText("pause");
        NetDemo.jButtonStopAlarmPlayBack.setEnabled(false);
        NetDemo.panelPlayLabel.repaint();
        NetDemo.jSliderAlarmPlayBack.setValue(0);
        NetDemo.jButtonMic.setVisible(true);
        NetDemo.jSliderLiveMicSound.setVisible(true);
        NetDemo.jLabelFrameRate.setText(null);
        NetDemo.jLabelBitRateParam.setText(null);
        NetDemo.jLabelVideoEncodeFmt.setText(null);
        NetDemo.jLabelGetpdwWidth.setText(null);
        NetDemo.jLabelGetpdwHeight.setText(null);
        NetDemo.jLabelGetpulRecvPktNum.setText(null);
        NetDemo.jLabelLiveViewStreamUrl.setText(null);
        NetDemo.lblAlarmProgressLabel.setText(null);
    }

    public static void pause() {
        if(null == NetDemo.lpUserID) {
            JOptionPane.showMessageDialog(null, "Please Login device first. error code"+NetDemo.netdevsdk.NETDEV_GetLastError());
            return;
        }
        if(NETDEV_VOD_PLAY_CTRL_E.NETDEV_PLAY_CTRL_PAUSE == NetDemo.PlayBackControlCmd) {
            boolean bRet = NetDemo.netdevsdk.NETDEV_PlayBackControl(NetDemo.lpPlayHandle, NETDEV_VOD_PLAY_CTRL_E.NETDEV_PLAY_CTRL_RESUME, null);
            if(bRet){
                NetDemo.PlayBackControlCmd = NETDEV_VOD_PLAY_CTRL_E.NETDEV_PLAY_CTRL_RESUME;
                NetDemo.jButtonPauseAlarmPlayBack.setText("pause");
            }
        }else {
            boolean bRet = NetDemo.netdevsdk.NETDEV_PlayBackControl(NetDemo.lpPlayHandle, NETDEV_VOD_PLAY_CTRL_E.NETDEV_PLAY_CTRL_PAUSE, null);
            if(bRet){
                NetDemo.PlayBackControlCmd = NETDEV_VOD_PLAY_CTRL_E.NETDEV_PLAY_CTRL_PAUSE;
                NetDemo.jButtonPauseAlarmPlayBack.setText("Resume");
            }
        }
    
    }
}
